<?php

namespace common\base;


use common\components\Option;
use yii\base\Application;
use yii\base\BootstrapInterface;
use yii\base\Component;
use yii\di\Instance;
use Yii;

class PluginManager extends Component implements BootstrapInterface
{
    /**
     * @var Application
     */
    protected $app;

    /**
     * @var Option
     */
    protected $option = 'option';

    public function init()
    {
        parent::init();
        $this->option = Instance::ensure('option', Option::className());
    }

    public function loadPlugins()
    {
        $activatePluginList = $this->option->get('active_plugin_list', array());
        foreach ($activatePluginList as $plugin) {
            $plugin->load();
        }
    }

    public function listPlugins()
    {
        $activatePluginList = $this->option->get('active_plugin_list', array());
        $pluginDir = Yii::getAlias('@plugins');
        $dh = opendir($pluginDir);
        $list = [];
        while($file = readdir($dh)) {
            if ($file == '.' || $file == '..' || !is_dir($pluginDir . '/' . $file)) {
                continue;
            }
            $pluginFile = $pluginDir . '/' . $file . '/Plugin.php';
            if (is_file($pluginFile )) {
                $className = "plugins\\{$file}\\Plugin";
                $plugin = new $className;
                if (isset($activatePluginList[$plugin->id])) {
                    $plugin->setActive();
                }
                $list[] = $plugin;
            }
        }
        return $list;
    }

    /**
     * @param Plugin[] $pluginList
     */
    public function install(array $pluginList)
    {
        foreach ($pluginList as $plugin)
        {
            $plugin->install();
            $plugin->setInstalled();
        }
    }

    /**
     * @param Plugin[] $pluginList
     */
    public function uninstall(array $pluginList)
    {
        $activatePluginList = $this->option->get('active_plugin_list', array());
        foreach ($pluginList as $plugin) {
            if (isset($activatePluginList[$plugin->getId()])) {
                $plugin->deactivate();
            }
            $plugin->uninstall();
        }
    }

    /**
     * @param Plugin[] $pluginList
     */
    public function activate(array $pluginList)
    {
        $activatePluginList = $this->option->get('active_plugin_list', array());
        foreach ($pluginList as $plugin) {
            if (isset($activatePluginList[$plugin->getId()])) {
                continue;
            }
            if (!$plugin->getIsInstalled()) {
                $this->install([$plugin]);
            }
            $plugin->activate();
            $activatePluginList[$plugin->getId()] = $plugin;
        }
        $this->option->set('activate_plugin_list', $activatePluginList);
    }

    /**
     * @param Plugin[] $pluginList
     */
    public function deactivate(array $pluginList)
    {
        $activatePluginList = $this->option->get('active_plugin_list', array());
        foreach ($pluginList as $plugin) {
            $plugin->deactivate();
            unset($activatePluginList[$plugin->getId()]);
        }
        $this->option->set('activate_plugin_list', $activatePluginList);
    }

    /**
     * Bootstrap method to be called during application bootstrap stage.
     * @param Application $app the application currently running
     */
    public function bootstrap($app)
    {
        $this->app = $app;
        $this->loadPlugins();
    }
}